<?php

namespace Kollway\CodeGenerator\Generators;

use Illuminate\Support\Str;

abstract class Generator implements GeneratorInterface
{
    // 表名(不带表前缀)
    protected $table;

    // 驼峰式的表名(用于 控制器、Model 的命名)
    protected $model_name;

    // 表的字段及注释信息
    protected $column_info;

    // 文件保存路径(相对项目根目录的路径)
    protected $file_path;

    // 文件名
    protected $file_name;

    // 文件内容
    protected $content;

    // yaml 配置选项
    protected $options;

    // 列表名称(xx 列表就配置为 xx)
    public $list_name = '';

    // 表单标题(新建／编辑 xx 就配置为 xx)
    public $form_title = '';

    // 表单类型(有部分只有单个输入框的表单使用弹窗方式)
    public $form_type = '';

    // 如果需要搜索，则填写。一个或多个, 多个的时候使用 yaml 的数组格式，单个的时候使用字符串
    public $search_fields = [];

    // 列表如果需要根据某些关键字搜索，则可以配置 搜索框的 placeholder
    public $search_placeholder = '';

    // 必填字段，一个或多个，会产生在 Model 类的 rules 属性
    public $required_fields = [];

    public $passwords = [];

    public $radios = [];

    public $checkboxes = [];

    public $images = [];

    public $textareas = [];

    public function __construct($table_name, $options)
    {
        $this->table = $table_name;
        $this->model_name = ucfirst(Str::camel($this->table));
        $this->column_info = DBUtils::getTableInfo($this->table);
        $this->setDefaultPathAndFilename();

        $this->options = $options;
        $this->processOptions();
    }

    // 处理选项, 把 null 或 空字符串 转换为对应类型的默认值
    private function processOptions()
    {
        $this->list_name = $this->options['list_name'] ?? '';
        $this->form_title = $this->options['form_title'] ?? '';
        $this->search_fields = $this->options['search_fields'] ?? '';
        $this->search_placeholder = $this->options['search_placeholder'] ?? '';
        $this->required_fields = $this->options['required_fields'] ?? '';
        $this->form_type = $this->options['form_type'] ?? '';

        $this->passwords = $this->options['passwords'] ?? [];
        $this->radios = $this->options['radios'] ?? [];
        $this->checkboxes = $this->options['checkboxes'] ?? [];
        $this->images = $this->options['images'] ?? [];
        $this->textareas = $this->options['textareas'] ?? [];
    }

    // 设置默认路径、文件名
    protected function setDefaultPathAndFilename()
    {
        switch (get_class($this)) {
            case ControllerGenerator::class:
                $this->file_path = 'app/Http/Controllers/Admin';
                $this->file_name = $this->model_name . 'Controller.php';
                break;
            case ModelGenerator::class:
                $this->file_path = 'app/Model';
                $this->file_name = $this->model_name . '.php';
                break;
            case FormViewGenerator::class:
                $this->file_path = 'resources/views/' . $this->table;
                $this->file_name = 'form.blade.php';
                break;
            case ListViewGenerator::class:
                $this->file_path = 'resources/views/' . $this->table;
                $this->file_name = 'list.blade.php';
                break;
            case ListDialogGenerator::class:
                $this->file_path = 'resources/views/' . $this->table;
                $this->file_name = $this->table . '_list_dialog.blade.php';
                break;
        }
    }

    /**
     * @param mixed $file_path
     */
    public function setFilePath($file_path)
    {
        $this->file_path = $file_path;
    }

    /**
     * @param mixed $file_name
     */
    public function setFileName($file_name)
    {
        $this->file_name = $file_name;
    }

    // 内容保存到文件
    public function writeToFile()
    {
        $absolute_path = base_path($this->file_path . DIRECTORY_SEPARATOR . $this->file_name);
        // 目录不存在则创建
        if (!is_dir(base_path($this->file_path))) {
            if (!mkdir(base_path($this->file_path), 0755, true)) {
                throw new \Exception('目录无法创建: ' . base_path($this->file_path));
            }
        }

        $resource = fopen($absolute_path, 'w+');
        fwrite($resource, $this->content);
        fclose($resource);
    }
}